<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/7/16 0016
 * Time: 2:31
 */

namespace api\storage\service;


use api\storage\model\FeedDetailModel;
use api\storage\model\FeedStationModel;
use api\storage\model\MachineModel;
use api\storage\model\MachineSeatModel;
use api\storage\model\ReelsModel;
use api\storage\model\SeatModel;
use api\storage\model\SmtMaterielModel;
use api\storage\model\SmtOutflowModel;
use api\storage\model\TransferModel;
use api\storage\model\ContainersModel;
use api\storage\model\SmtInflowModel;
use service\logger\LoggerFactory;
use tests\CropTest;
use think\Db;

class SmtReturnService extends BaseService
{

    protected $file;
    protected $transferModel;
    protected $feedDetailModel;
    protected $machineModel;
    protected $feedStationModel;
    protected $machineSeatModel;
    protected $smtMaterielModel;
    protected $reelsModel;
    protected $storageUuid;
    protected $smtOutflowModel;
    protected $seatModel;
    protected $containersModel;
    protected $smtInflowModel;
    protected $logger;
    /**
     * MachineServer constructor.
     */
    public function __construct()
    {
        $this->transferModel = new TransferModel();
        $this->feedDetailModel = new FeedDetailModel();
        $this->machineModel = new MachineModel();
        $this->feedStationModel = new FeedStationModel();
        $this->machineSeatModel = new MachineSeatModel();
        $this->smtMaterielModel = new SmtMaterielModel();
        $this->reelsModel = new ReelsModel();
        $this->smtOutflowModel = new SmtOutflowModel();
        $this->seatModel = new SeatModel();
        $this->containersModel = new ContainersModel();
        $this->smtInflowModel = new SmtInflowModel();
        $this->logger = LoggerFactory::getLogger('return');
    }

    /***
     * @param $reelId
     * @param $returnCount
     * @param string $storageUuid
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\Exception
     * @throws \Exception
     * 从机器上卸料
     */
    public function unloadFromMachineSeat($reelId,$returnCount, $storageUuid = "184928afb9e35f3ff421da05fc3f917f" ){

        $machineSeatObject = $this->machineSeatModel->findMachineSeatInfo(['reel_id' => $reelId]);
        if(empty($machineSeatObject)){
            return $this->resultTemplate(1);//该物料不在机器上
        }
        $machineSeat = $machineSeatObject->toArray();
        if($machineSeat['status'] == 0){
            return $this->resultTemplate(3,['machineId' => $machineSeat['machine_id'],'seatCode' => $machineSeat['seat_code']]);
        }


        $machineClear = [
            'status' => 1,
            'reel_id' => "",
            'count' => "0",
            'sub_materiel_id' => "",
            'is_used'=> 0
        ];


        $machine = $this->machineModel->findMachineInfo(['uuid' => $machineSeat['machine_uuid']])->toArray();


        $feedDetail = $this->feedDetailModel->findFeedDetailBy3Condition($machine['feed_uuid'],$machineSeat['machine_uuid'],$machineSeat['seat_code'])->toArray();
        if($feedDetail['sent_count'] < $feedDetail['total_count']){
            return $this->resultTemplate(4);
        }
        if( ($feedDetail['sent_count']  - $returnCount) < $feedDetail['total_count'] ){
            return $this->resultTemplate(5);
        }
        $this->machineSeatModel->updateMachineSeat(['uuid' => $machineSeat['uuid']],$machineClear);//清空站位上的物料的信息
        $transfer = [
            'uuid' => md5(create_uuid()),
            'feed_detail_uuid' => $feedDetail['uuid'],
            'reel_id' => $machineSeat['reel_id'] ,
            'sub_materiel_id' => $feedDetail["sub_materiel_id"],
            'status' =>  1,
            'count' => $returnCount,
            'storage_uuid' => $storageUuid,
        ];

        $this->transferModel->add($transfer);//增加中转记录

        $feedDetail['sent_count'] -= $returnCount;//修改已发数量
        $feedDetail['waste'] = $feedDetail['sent_count'] - $feedDetail['total_count'];//修改物料损耗的数量
        $feedDetail['status'] = 0;
        $this->feedDetailModel->updateFeedDetail(['uuid' => $feedDetail['uuid']],$feedDetail);//修改料站细表状态

        $unFinish1 = $this->feedDetailModel->checkFeedStatus($feedDetail['feed_id']);//查询未完成的料站细表记录的数量
        if($unFinish1 == 0){
            $this->feedStationModel->updateFeed(['feed_id' => $feedDetail['feed_id'] ,'storage_uuid' => $storageUuid],['status' => 2]);//将工单状态设置为已完成
        }
        $unFinish2 = $this->machineSeatModel->checkMachineStatus($machine['uuid']);
        if ($unFinish2 == 0){
            $this->machineModel->updateMachine(['uuid' => $machine['uuid']],['feed_uuid' => "",'feed_id' => ""]);
            $this->logger->info("机台上的站位已全部清空，清除机器上的工单号：{$feedDetail['feed_id']}");
        }
//     更新模拟量，以及checkTime
        $this->smtMaterielModel->startTrans();
        $smtMateriel = $this->smtMaterielModel->findByLock(['sub_materiel_id' => $feedDetail["sub_materiel_id"]])->toArray();
        $changeSimulation = ($smtMateriel['simulation_num'] - $feedDetail['waste']);//修改后的模拟量
        $changeWaste = $smtMateriel['waste'] + $feedDetail['waste'];
        $this->smtMaterielModel->updateMaterielWithLock(['simulation_num' => $changeSimulation, 'waste' => $changeWaste],['sub_materiel_id' => $feedDetail["sub_materiel_id"]]);
        $this->smtMaterielModel->updateCheckTime(['sub_materiel_id' => $feedDetail["sub_materiel_id"]]);
        $this->smtMaterielModel->commit();
        $this->logger->info("从机器上卸下物料。物料条码：{$reelId} 归还数量：{$returnCount} 机器号：{$machine['machine_id']} 站位号：{$machineSeat['seat_code']} 物料号：{$feedDetail["sub_materiel_id"]} 修改后的模拟量：{$changeSimulation} 浪费的数量：{$changeWaste}");
        return $this->resultTemplate(2);
    }

    /***
     * @param $reelId
     * @param string $storageUuid
     * @return array
     * @throws \think\Exception
     * 检查要归还的盘料
     */
    public function checkReturn($reelId, $storageUuid = "184928afb9e35f3ff421da05fc3f917f"){
        $reelObj = $this->transferModel->findReel(['reel_id' => $reelId, 'storage_uuid' => $storageUuid]);//在中转区寻找reel
        if(empty($reelObj)){
            return $this->resultTemplate(3);
        }




        $reel = $reelObj->toArray();
        switch ($reel['status']){//当前扫码的缓冲区物料的状态
            case 0:
                return $this->resultTemplate(0);//该物料是准备上机的物料
                break;
            case 1:
                return $this->resultTemplate(1,$reel['count']);//请扫描站位码或容器号
                break;
            case 2:
                return $this->resultTemplate(2);//该物料是移料物料
                break;
        }
    }

    /****
     * @param $reelId
     * @param $seatCode
     * @param $containerCode
     * @param $storageUuid
     * @param $userId
     * @return array
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException 退料入库
     * @throws \Exception
     */
    public function smtInput($reelId, $seatCode, $containerCode, $storageUuid = "184928afb9e35f3ff421da05fc3f917f" , $username){

        $transferObject = $this->transferModel->findReel(['reel_id' => $reelId]);
        if(empty($transferObject)){//该物料是否存在于中转区中
            return $this->resultTemplate(2);
        }
        $transfer = $transferObject->toArray();
        $time = date("Y-m-d H:i:s",strtotime("now"));//时间

        if(empty($containerCode)){//容器号为空，站位入库
            $result =  $this->shelveInput($transfer, $seatCode,$storageUuid,$time,$username);//站位入库
            if($result == true){//为真说明发生错误中断
                return $result;//将错误原因的resultTemplate返回
            }
        }

        else{//容器号不为空，说明扫描的是容器
            $result =  $this->containerInput($transfer, $containerCode,$storageUuid,$time,$username);//容器入库
            if($result == true){//为真说明发生中断
                return $result; //将错误原因的resultTemplate返回
            }
        }
        $this->transferModel->deleteByUuid($transfer['uuid']);
        $this->smtMaterielModel->startTrans();
        $materiel = $this->smtMaterielModel->findByLock(['sub_materiel_id' => $transfer['sub_materiel_id']]);
        $count =  $materiel['total_num'] + $transfer['count']; //更新total_num数量
        $update['total_num'] = $count;
        $where['sub_materiel_id'] = $materiel['sub_materiel_id'];
        $this->smtMaterielModel->updateMaterielWithLock($update,$where);
        $this->smtMaterielModel->commit();
        $this->logger->info("还料入库： 物料条码：{$reelId} 归还站位：{$seatCode} 归还容器：{$containerCode} userId：{$username} 物料号:{$materiel['sub_materiel_id']} 在库总数：{$count}");
        return $this->resultTemplate(1);

    }

    /***
     * @param $transfer
     * @param $seatCode
     * @param $storageUuid
     * @param $time
     * @param $username
     * @return array|bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException 容器入库
     */
    protected function shelveInput($transfer, $seatCode,$storageUuid,$time,$username){
        $result = $this->seatModel->findSeatCodeByWhere(['seat_code' => $seatCode, 'storage_uuid' => $storageUuid]);
        if (empty($result)){
            return $this->resultTemplate(5);//该站位不存在
        }
        $seat = $result->toArray();
        if ($seat['is_used'] == 1){
            return $this->resultTemplate(4);
        }
        if($seat['status'] != 0){
            return $this->resultTemplate(3);
        }

        $this->transferModel->deleteByUuid($transfer['uuid']);//删除中转表中的数据
        $reels = [
            'uuid' => md5(create_uuid()),
            'reel_id' => $transfer['reel_id'],
            'count' => $transfer['count'],
            'seat_code' => $seatCode,
            'storage_uuid' => $storageUuid,
            'time' => $time,
            'status' => 1,

        ];

        $this->reelsModel->add($reels);//增加reel表数据
        $this->seatModel->updateByCodeAndUuid($seatCode,$storageUuid,['is_used' => 1]);//更新对应站位
        $inflow = [
            'uuid' => md5(create_uuid()),
            'reel_id' => $transfer['reel_id'],
            'count' => $transfer['count'],
            'sub_materiel_id' => $transfer['sub_materiel_id'],
            'seat_code' => $seatCode,
            'storage_uuid' => $storageUuid,
            'time' => $time,
            'feed_detail_uuid' => $transfer['feed_detail_uuid'],
            'remark' => '机器退料入库',
            'user_login' => $username,
            'status' => 1
        ];

        $this->smtInflowModel->add($inflow);

        return false;//若为false说明他们未出现错误中断
    }

    /**
     * @param $transfer
     * @param $containerCode
     * @param $storageUuid
     * @param $time
     * @param $userId
     * @return array|bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException 容器入库
     */
    protected function containerInput($transfer, $containerCode,$storageUuid,$time,$username){
        $containerObj = $this->containersModel->findByContainerCode($containerCode);
        if(empty($containerObj)){//容器不存在
            return $this->resultTemplate(6);
        }
        $container = $containerObj->toArray();
        if($container['status']  == 0){//未上架
            return $this->resultTemplate(7);
        }
        $this->transferModel->deleteByUuid($transfer['uuid']);//删除中转表中的数据
        $reels = [
            'uuid' => md5(create_uuid()),
            'reel_id' => $transfer['reel_id'],
            'count' => $transfer['count'],
            'seat_code' => $container['seat_code'],
            'storage_uuid' => $storageUuid,
            'time' => $time,
            'status' => 1,
            'sub_materiel_id' => $transfer['sub_materiel_id'] ,
            'container_code' => $containerCode
        ];
        $this->reelsModel->add($reels);//增加reel表数据


        $inflow = [
            'uuid' => md5(create_uuid()),
            'reel_id' => $transfer['reel_id'],
            'count' => $transfer['count'],
            'sub_materiel_id' => $transfer['sub_materiel_id'],
            'seat_code' => $container['seat_code'],
            'storage_uuid' => $storageUuid,
            'time' => $time,
            'feed_detail_uuid' => $transfer['feed_detail_uuid'],
            'remark' => '机器退料入库',
            'user_login' => $username,
            'status' => 1
        ];
        $this->smtInflowModel->add($inflow);
        return false;
    }



}